﻿/*
Copyright (c) 2010 Vratislav Cermak (vratacermak@gmail.com)
 
This file is part of TeachMe Project. See http://code.google.com/p/teach-me for more information.
 
TeachMe is an open source project. Using of TeachMe is free of charge.
It is distributed under GNU General Public License version 3 (GPLv3).
GPLv3 can be found at http://www.gnu.org/licenses/gpl.html.
 
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using TeachMe.Application.Configuration;
using TeachMe.Application.Events;

namespace TeachMe.Application.Forms
{
    public partial class SymbolsForm : Form
    {
        public event EventHandler<SymbolEventArgs> SymbolSelected;

        private readonly Root _root;
        private char? _currentSelection;

        public SymbolsForm(Root root)
        {
            _root = root;
            _root.UserSettings.Symbols.Changed += OnSymbolsChanged;

            InitializeComponent();
            
            WindowProportions.Lock(this, _root.MachineSettings);
        }

        void OnSymbolsChanged(object sender, EventArgs e)
        {
            ccMain.SetSymbols(_root.UserSettings.Symbols.Value != null ? _root.UserSettings.Symbols.Value.ToCharArray() : null);
        }

        void OnSymbolSelected(object sender, SymbolEventArgs e)
        {
            FireSymbolSelected(e.Symbol);
        }

        private void OnResize(object sender, EventArgs e)
        {
            ccMain.Width = pTopContainer.Width;
        }

        private void OnNewSymbolsTextChanged(object sender, EventArgs e)
        {
            bAdd.Enabled = tbNewSymbols.Text.Trim().Length > 0;
        }

        private void OnAddClick(object sender, EventArgs e)
        {
            char[] newSymbols = tbNewSymbols.Text.Trim().ToCharArray();
            List<char> existingSymbols = new List<char>();
            if (_root.UserSettings.Symbols.Value != null) 
            {
                existingSymbols.AddRange(_root.UserSettings.Symbols.Value);
            }
            foreach (var newSymbol in newSymbols) 
            {
                bool exists = false;
                foreach (var existingSymbol in existingSymbols)
                {
                    if (newSymbol == existingSymbol) 
                    {
                        exists = true;
                        break;
                    }
                }
                if (!exists) 
                {
                    existingSymbols.Add(newSymbol);
                }
            }
            using (_root.UserSettings.Edit()) 
            {
                _root.UserSettings.Symbols.Value = new string(existingSymbols.ToArray());
            }
        }

        private void OnInsertMenuItemClick(object sender, EventArgs e)
        {
            if (_currentSelection.HasValue) 
            {
                FireSymbolSelected(_currentSelection.Value);
            }
        }

        private void FireSymbolSelected(char selection)
        {
            EventHandler<SymbolEventArgs> handler = SymbolSelected;
            if (handler != null)
            {
                handler(this, new SymbolEventArgs { Symbol = selection });
            }
        }

        private void OnSymbolsContextMenuOpening(object sender, System.ComponentModel.CancelEventArgs e)
        {
            miInsert.Enabled = ccMain.IsValidSelection;
            miRemove.Enabled = ccMain.IsValidSelection;
            miRemoveAll.Enabled = !String.IsNullOrEmpty(_root.UserSettings.Symbols.Value);

            if (ccMain.IsValidSelection) 
            {
                _currentSelection = ccMain.CurrentSelection;
            }
            else 
            {
                _currentSelection = null;
            }
        }

        private void OnRemoveMenuItemClick(object sender, EventArgs e)
        {
            if (!_currentSelection.HasValue) 
            {
                throw new InvalidOperationException();
            }

            List<char> existingSymbols = new List<char>(_root.UserSettings.Symbols.Value);

            using (_root.UserSettings.Edit()) 
            {
                _root.UserSettings.Symbols.Value = new string(existingSymbols.Where(existingSymbol => existingSymbol != _currentSelection).ToArray());
            }
        }

        private void OnRemoveAllClick(object sender, EventArgs e)
        {
            using (_root.UserSettings.Edit())
            {
                _root.UserSettings.Symbols.Value = String.Empty;
            }
        }

        private void OnShown(object sender, EventArgs e)
        {
            ccMain.Selected += OnSymbolSelected;
            ccMain.SetSymbols(_root.UserSettings.Symbols.Value != null ? _root.UserSettings.Symbols.Value.ToCharArray() : null);
            ccMain.Width = pTopContainer.Width;
        }
    }
}
